# -*- coding: utf-8 -*-
from __future__ import unicode_literals

import re
# import json
import xlrd
import operator
from functools import reduce
# from io import BytesIO

from django.db.models import Q
# from django.conf import settings
from django.utils.timezone import datetime

from idcops.lib.utils import shared_queryset
from idcops.models import (
    Option, Rack, Client, Unit, Pdu, User, Online
)


CreatorId = 1


def import_online(path, onidc_id):
    fileds = [
        'name', 'creator', 'rack', 'client', 'created', 'onidc',
        'sn', 'model', 'ipaddr', 'style', 'units', 'pdus'
    ]
    workbook = xlrd.open_workbook(path)
    sheets = workbook.sheet_names()
    worksheet = workbook.sheet_by_name(sheets[0])
    # 设置导入错误日志记录到一个字典中
    handler_error = []
    # handler_success = dict()
    for index, row in enumerate(worksheet.get_rows(), 1):
        error = dict()
        header = index
        if header == 1:
            # 跳过表头
            continue
        if header == 2:
            # 获取字段名称
            headers = [h.value for h in row]
            continue
        data = dict(zip(headers, [k.value for k in row]))
        raw = {k: data.get(k) for k in fileds}
        # 处理带有年月日的中文日期时间
        _created = re.sub('年|月', '-', data.get('created')).replace('日', '')
        created = datetime.strptime(_created, '%Y-%m-%d %H:%M')
        raw.update(**dict(created=created))
        verify = Online.objects.filter(name=raw.get('name'))
        if verify.exists():
            msg = "{} 设备已存在".format(raw.get('name'))
            error[index] = msg
            handler_error.append(error)
            continue
        else:
            style = get_or_create_style(raw.get('style'), onidc_id)
            creator = get_creator(raw.get('creator'))
            # 获取机柜信息
            rack, err = get_rack(raw.get('rack'), onidc_id)
            if not rack:
                error[index] = "第{}行：{}".format(index, err)
                handler_error.append(error)
                continue
            # 获取客户信息
            client, err = get_or_create_client(raw.get('client'), onidc_id)
            if not client:
                error[index] = "第{}行：{}".format(index, err)
                handler_error.append(error)
                continue
            # 实例化在线设备
            instance = Online(
                created=created, style=style, creator=creator,
                rack=rack, client=client, name=raw.get('name'),
                sn=raw.get('sn'), ipaddr=raw.get('ipaddr'),
                model=raw.get('model'), onidc_id=onidc_id
            )
            instance.save()
            # 保存U位
            units, err = clean_units(raw.get('units'), rack.pk)
            if units:
                for u in units:
                    instance.units.add(u)
                units.update(actived=False)
                instance.save()
            else:
                error[index] = "第{}行：{}".format(index, err)
                handler_error.append(error)
                # U位不对，删除本实例
                instance.delete()
                continue
            # 保存PDU
            pdus, err = clean_pdus(raw.get('pdus'), rack.pk)
            if pdus:
                for p in pdus:
                    instance.pdus.add(p)
                pdus.update(actived=False)
                instance.save()
            else:
                error[index] = "第{}行：{}".format(index, err)
                handler_error.append(error)
                continue
    return handler_error


def get_creator(username):
    fields = ['first_name', 'username', 'mobile']
    query = [Q(**{k: username}) for k in fields]
    query_str = reduce(operator.or_, query)
    user = User.objects.filter(query_str)
    if user.exists():
        return user.first()
    else:
        return User.objects.filter().order_by('-pk').first()


def get_or_create_style(name, onidc_id):
    f = dict(
        onidc_id=onidc_id, flag='Device-Style', text=name
    )
    qs = shared_queryset(Option.objects.filter(**f), onidc_id)
    if qs.exists():
        instance = qs.first()
    else:
        extra = dict(
            description=name,
            creator_id=CreatorId
        )
        f.update(**extra)
        instance = Option.objects.create(**f)
    return instance


def get_or_create_client(name, onidc_id):
    qs = Client.objects.filter(name=name)
    if qs.exists():
        instance = qs.first()
    else:
        types = Option.objects.filter(
            onidc_id=onidc_id, flag='Client-Style'
        )
        if types.exists():
            default = types.filter(master=True)
            if default.exists():
                style = default.first()
            else:
                style = types.first()
        else:
            return None, "客户类型不能为空"
        instance = Client.objects.create(
            onidc_id=onidc_id, creator_id=CreatorId, name=name, style=style
        )
    return instance, None


def get_rack(name, onidc_id):
    """
    Return: (instance, error)
    """
    qs = Rack.objects.filter(name=name, onidc_id=onidc_id)
    if qs.filter(actived=True).exists():
        return qs.first(), None
    elif qs.filter(actived=False).exists():
        return None, "该机柜未分配使用"
    else:
        return None, "找不到该机柜"


def clean_units(data, rack_id):
    units = sorted([int(i) for i in data.split(',') if len(i) != 0])
    units_list = [
        str(x).zfill(2) for x in range(units[0], units[-1]+1)
    ]
    instances = Unit.objects.filter(rack_id=rack_id, name__in=units_list)
    if instances.exists():
        used = instances.filter(actived=False)
        if used.count() > 0:
            return None, "有U位被占用中"
        return instances, None
    else:
        return None, "找不到U位信息"


def clean_pdus(data, rack_id):
    pdus = re.split('[, |]', data)
    pdus_list = [x.strip() for x in pdus if x]
    instances = Pdu.objects.filter(rack_id=rack_id, name__in=pdus_list)
    if instances.exists():
        used = instances.filter(actived=False)
        if used.count() > 0:
            return instances.filter(actived=True), "部分PDU位被占用中"
        return instances, None
    else:
        return None, "找不到PDU位信息"
